package com.xuecheng.content.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.AuthInfo;
import com.xuecheng.commons.model.vo.CourseBaseVo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioTemplate;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import io.minio.errors.*;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author HuangYuwu
 * @since 2022-09-11
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    TeachplanService teachplanService;
    @Autowired
    private MinioTemplate minioTemplate;
    /**
     * 课程信息分页查询
     * @param request
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findByPage(PageRequest request, CourseDto dto) {
        // 1.构建分页
        Page<CourseBase>page=new Page<>(request.getPageNo(),request.getPageSize());
        // 2.构建条件
        LambdaQueryWrapper<CourseBase>queryWrapper=new LambdaQueryWrapper<>();
        // 课程名称
        String courseName = dto.getCourseName();
        queryWrapper.like(StrUtil.isNotBlank(courseName),CourseBase::getName,courseName);
        // 课程状态
        String auditStatus = dto.getAuditStatus();
        queryWrapper.eq(StrUtil.isNotBlank(auditStatus),CourseBase::getAuditStatus,auditStatus);
        // 课程类型
        String teachmode = dto.getTeachmode();
        queryWrapper.eq(StrUtil.isNotBlank(teachmode),CourseBase::getTeachmode,teachmode);
        // 3.执行分页查询
        page = this.page(page, queryWrapper);
        // 4.转vo
        List<CourseBase> courseBaseList = page.getRecords();
        List<CourseBaseVo> courseBaseVoList = BeanHelper.copyWithCollection(courseBaseList, CourseBaseVo.class);
        // 5.返回分页结果
        return PageResponseResult.okResult(page.getTotal(),courseBaseVoList);
    }

    @Override
    public ResponseResult  saveCourseBase(CourseBaseDto courseBaseDto) {
        //参数合法性校验
        if(StrUtil.isBlank(courseBaseDto.getTags())||StrUtil.isBlank(courseBaseDto.getName())){
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //dto->entity

        CourseBase courseBase = BeanHelper.copyProperties(courseBaseDto, CourseBase.class);
        //补充信息
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);
        courseBase.setCreateDate(DateUtil.date());
        courseBase.setPlanNum(0);
        AuthInfo authInfo = AuthInfoHolder.getAuthInfo();
        if (authInfo!=null){
            courseBase.setCompanyName(authInfo.getCompanyName());
        }
        //保存数据库
        boolean save = this.save(courseBase);
        if (!save){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //初始化课程一级大纲
        Teachplan teachplan=new Teachplan();
        teachplan.setCourseId(courseBase.getId());
        teachplan.setPname(courseBase.getName());
        teachplan.setDescription(courseBase.getDescription());
        teachplan.setCreateDate(DateUtil.date());
        teachplan.setParentid(0L);
        teachplan.setGrade(1);
        teachplanService.save(teachplan);

        //返回结果
        Map map=new HashMap();
        map.put("courseBaseId",courseBase.getId());
        return ResponseResult.okResult(map);
    }

    @Override
    public ResponseResult updateCourseBase(CourseBaseDto dto) {
        //根据课程id查询数据库
        CourseBase courseBase = this.getById(dto.getId());
        //判断状态是否为可修改
        String auditStatus = courseBase.getAuditStatus();
        if (StrUtil.equals(auditStatus,CourseConstants.AUDIT_COMMIT_STATUS)||
                StrUtil.equals(auditStatus,CourseConstants.AUDIT_PASTED_STATUS)||
                StrUtil.equals(auditStatus,CourseConstants.AUDIT_PUBLISHED_STATUS)){
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        //dot->courseBase
        BeanUtils.copyProperties(dto,courseBase);
        //更新新数据库
        boolean update = this.updateById(courseBase);
        if (!update){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //更新课程一级大纲
        LambdaQueryWrapper<Teachplan>queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseBase.getId());
        queryWrapper.eq(Teachplan::getGrade,1);
        Teachplan teachplan=new Teachplan();
        teachplan.setPname(courseBase.getName());
        teachplan.setDescription(courseBase.getDescription());
        teachplan.setChangeDate(DateUtil.date());
        teachplanService.update(teachplan,queryWrapper);
        //返回课程id
        Map map=new HashMap();
        map.put("courseBaseId",courseBase.getId());
        return ResponseResult.okResult(map);
    }

    /**
     * 根据课程id删除课程
     * @param courseId
     * @return
     */
    @Override
    @Transactional
    public ResponseResult deleteCourseBaseById(Long courseId) throws ServerException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //根据课程id查询数据库
        CourseBase courseBase = this.getById(courseId);
        //判断状态是否为可修改
        String auditStatus = courseBase.getAuditStatus();
        if (StrUtil.equals(auditStatus,CourseConstants.AUDIT_PUBLISHED_STATUS)){
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId );
        List<Teachplan> list = teachplanService.list(queryWrapper);
        if (list.size()>1){
            //课程下有章节时不允许删除
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        minioTemplate.deleteImage(courseBase.getPic());
        teachplanService.remove(queryWrapper);
        this.removeById(courseId);
        return ResponseResult.okResult();
    }

    /**
     * 机构提交审核课程
     * @param courseBaseId
     * @return
     */
    @Override
    public ResponseResult commitCourseBase(Long courseBaseId) {
       /* CourseBase courseBase = this.getById(courseBaseId);
        courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        this.updateById(courseBase);
        return ResponseResult.okResult();*/
        // 1.创建课程信息
        CourseBase courseBase = new CourseBase();
        // 2.设置数据
        courseBase.setId(courseBaseId);
        courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        AuthInfo authInfo = AuthInfoHolder.getAuthInfo();
        if (authInfo!=null){
            courseBase.setCompanyName(authInfo.getCompanyName());
        }
        // 3.更新数据库
        this.updateById(courseBase);
        return ResponseResult.okResult();
    }

    /**
     * 管理员审核课程
     * @param courseAuditDto
     * @return
     */
    @Override
    public ResponseResult approveCourseBase(CourseAuditDto courseAuditDto) {
        CourseBase courseBase = this.getById(courseAuditDto.getCourseBaseId());
        courseBase.setAuditStatus(courseAuditDto.getAuditStatus());
        courseBase.setAuditDate(DateUtil.date());
        courseBase.setAuditMind(courseAuditDto.getAuditMind());
        this.updateById(courseBase);
        return ResponseResult.okResult();
    }
}
